package com.sound.ampache;

/* Copyright (c) 2010 Brian Kirkman <kirkman.brian@gmail.com>
*
* +------------------------------------------------------------------------+
* | This program is free software; you can redistribute it and/or          |
* | modify it under the terms of the GNU General Public License            |
* | as published by the Free Software Foundation; either version 3         |
* | of the License, or (at your option) any later version.                 |
* |                                                                        |
* | This program is distributed in the hope that it will be useful,        |
* | but WITHOUT ANY WARRANTY; without even the implied warranty of         |
* | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          |
* | GNU General Public License for more details.                           |
* |                                                                        |
* | You should have received a copy of the GNU General Public License      |
* | along with this program; if not, write to the Free Software            |
* | Foundation, Inc., 59 Temple Place - Suite 330,                         |
* | Boston, MA  02111-1307, USA.                                           |
* +------------------------------------------------------------------------+
*
* Special thanks to the following: 
* Kevin Purdy, author of Amdroid, for much of the code used in this project
* 
* Jorge Ramon, author of MiamiCoder blog, for many great BlackBerry examples
* published on his blog.
* 
* 
*/

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.system.GIFEncodedImage;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.Graphics;


public class SplashScreen extends MainScreen {
	private static final Bitmap _bitmap = Bitmap.getBitmapResource("amdroid_icon.png");
	private AnimatedGIFField _ourAnimation = null;
	
	private SplashScreen() {
		super(Field.USE_ALL_HEIGHT | Field.FIELD_LEFT);

		GIFEncodedImage ourAnimation = (GIFEncodedImage) GIFEncodedImage.getEncodedImageResource("cycle.agif");
		_ourAnimation = new AnimatedGIFField(ourAnimation, Field.FIELD_HCENTER);
      
		this.add(new SpacerField((Display.getHeight() - _bitmap.getHeight() - 20 - (Font.getDefault().getHeight()*2))/2));
		this.add(new BitmapField(_bitmap, BitmapField.HCENTER));
		this.add(new LabelField("Ampacheberry", LabelField.USE_ALL_WIDTH | DrawStyle.HCENTER));
		this.add(new SpacerField(10));
		this.add(_ourAnimation);
		this.add(new SpacerField(10));
		this.add(new LabelField("Connecting...", LabelField.USE_ALL_WIDTH | DrawStyle.HCENTER));
	}
   

   	public static void showScreen(final Runnable runThis) {
   		final SplashScreen thisScreen = new SplashScreen();
   		
   		Thread threadToRun = new Thread() {
   			public void run() {
   				// First, display this screen
   				UiApplication.getUiApplication().invokeLater(new Runnable() {
   					public void run() {
   						UiApplication.getUiApplication().pushScreen(thisScreen);
   					}
   				});
   
   				// Now run the code that must be executed in the Background
   				try {
   					runThis.run();
   				} catch (Throwable t) {
   					t.printStackTrace();
   					throw new RuntimeException("Exception detected while waiting: " + t.toString());
   				}
   
   				// Now refresh homescreen, dismiss this screen, and push homescreen if not on stack
               UiApplication.getUiApplication().invokeLater(new Runnable() {
                   	public void run() {
                   		ampacheberry.redrawHomescreen();
                   		
            	    	try {
            	    		UiApplication.getUiApplication().popScreen(thisScreen);
            	    	} catch(IllegalArgumentException e) {
            	    		/*screen is not on the stack - do nothing*/
            	    	}
                       
           	    		if (!ampacheberry.homeScreen.isDisplayed()) {
           	    			UiApplication.getUiApplication().pushScreen(ampacheberry.homeScreen);
           	    		}
                   }
               });
           }
       };
       threadToRun.start();
   }
	   
	   
   private class SpacerField extends Field {
	    private int _height;

	    public SpacerField(int height) {
	        super(Field.READONLY);
	        _height = height;
	    }

	    public void layout(int widht, int hieght) {
	        setExtent(Display.getWidth(), _height);
	    }

	    public void paint(Graphics g) {
	    }
	}
   
   
   public class AnimatedGIFField extends BitmapField 
   {
       private GIFEncodedImage _image;     //The image to draw.
       private int _currentFrame;          //The current frame in the animation sequence.
       private AnimatorThread _animatorThread;
       
       public AnimatedGIFField(GIFEncodedImage image)
       {
           this(image, 0);
       }
       
       public AnimatedGIFField(GIFEncodedImage image, long style)
       {
           //Call super to setup the field with the specified style.
           //The image is passed in as well for the field to configure its required size.
           super(image.getBitmap(), style);
           
           //Store the image.
           _image = image;
           
           //Start the animation thread.
           _animatorThread = new AnimatorThread(this);
           _animatorThread.start();
       }
       
       protected void paint(Graphics graphics)
       {
           //Call super.paint.  This will draw the first background frame and handle any required focus drawing.
           super.paint(graphics);
           
           //Don't redraw the background if this is the first frame.
           if (_currentFrame != 0)
           {
               //Draw the animation frame.
               graphics.drawImage(_image.getFrameLeft(_currentFrame), _image.getFrameTop(_currentFrame), 
                   _image.getFrameWidth(_currentFrame), _image.getFrameHeight(_currentFrame), _image, _currentFrame, 0, 0);
           }
       }
       
       //Stop the animation thread when the screen the field is on is
       //popped off of the display stack.
       protected void onUndisplay()
       {
           _animatorThread.stop();
           super.onUndisplay();
       }
       
      
       //A thread to handle the animation.
       private class AnimatorThread extends Thread
       {
           private AnimatedGIFField _theField;
           private boolean _keepGoing = true;      
           private int _totalFrames;               //The total number of frames in the image.
           private int _loopCount;                 //The number of times the animation has looped (completed).
           private int _totalLoops;                //The number of times the animation should loop (set in the image).

           public AnimatorThread(AnimatedGIFField theField)
           {
               _theField = theField;
               _totalFrames = _image.getFrameCount();
               _totalLoops = _image.getIterations();
               
           }
           
           public synchronized void stop()
           {
               _keepGoing = false;
           }
           
           public void run()
           {
               while(_keepGoing)
               {
                   //Invalidate the field so that it is redrawn.
                   UiApplication.getUiApplication().invokeAndWait(new Runnable() 
                   {
                       public void run() 
                       {
                           _theField.invalidate();                    
                       }
                   });                
                   
                   try
                   {
                       //Sleep for the current frame delay before the next frame is drawn.
                       sleep(_image.getFrameDelay(_currentFrame) * 10);
                   }
                   catch (InterruptedException iex)
                   {} //Couldn't sleep.
                   
                   //Increment the frame.
                   ++_currentFrame;      
                   
                   if (_currentFrame == _totalFrames)
                   {
                       //Reset back to frame 0 if we have reached the end.
                       _currentFrame = 0;
                       
                       ++_loopCount;
                       
                       //Check if the animation should continue.
                       if (_loopCount == _totalLoops)
                       {
                           _keepGoing = false;
                       }
                   }
               }
           }
       }
   }
   
} 
